コンテナイメージ版AWS Lambda関数をCloudFormationでデプロイしてみた
デプロイをCloudFormationテンプレート(IaC)化すると、デプロイパイプラインにスムーズに組み込むことができます。
今回は、コンテナイメージ版LambdaをCloudFormationでデプロイする方法を紹介します。
コンテナLambdaをデプロイするCloudFormation テンプレート
コンテナLambda(非VPC版)をデプロイするには、次のテンプレートを利用します。
AWSTemplateFormatVersion: '2010-09-09' Parameters: EcrImageUri: Description: ECR image URI Type: String Resources: LambdaFunc: Type: AWS::Lambda::Function Properties: Role: Fn::GetAtt: - LambdaRole - Arn PackageType: Image Code: ImageUri: !Ref 'EcrImageUri' Architectures: - x86_64 MemorySize: 512 Timeout: 30 LambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
コンテナ Lambda固有の記述について、かいつまんで紹介します。
コンテナ固有のプロパティ
コンテナLambdaの場合、 PackageType
プロパティに Image
を設定し、
コンテナイメージのURIを Code
プロパティで指定します。
Properties: ... PackageType: Image Code: ImageUri: ECRのURI ...
本テンプレートでは、イメージURIをパラメーター化しています。
不要なプロパティ
コンテナLambdaの場合、以下のプロパティは不要です。
Runtime
(nodejs14.x
など)Handler
(index.handler
など)
コンテナLambdaをCloudFormationでデプロイしてみる
作成した CloudFormation テンプレートを利用し、コンテナLambdaをデプロしてみます。
ECR の作成
まずは、コンテナレジストリのAmazon Elastic Container Registry (ECR)を作成します。
$ aws ecr create-repository --repository-name test { "repository": { "repositoryArn": "arn:aws:ecr:eu-central-1:123:repository/test", "registryId": "123", "repositoryName": "test", "repositoryUri": "123.dkr.ecr.eu-central-1.amazonaws.com/test", "createdAt": "2022-01-03T21:06:35+01:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": false }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
アプリケーションの作成
次に動作確認用 Python アプリケーションを作成します。
app.py
と Dockerfile
の2ファイルを作成します。
app.py
import sys def handler(event, context): return 'Hello from AWS Lambda using Python' + sys.version + '!'
Dockerfile
FROM public.ecr.aws/lambda/python:3.9 COPY app.py ${LAMBDA_TASK_ROOT} CMD [ "app.handler" ]
イメージをビルド
このイメージをビルドします。
$ docker build -t test:latest .
ローカルで動作確認します。
# コンテナ起動用ターミナル $ docker run -p 9000:8080 test:latest # クライアント用ターミナル $ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}' "Hello from AWS Lambda using Python3.9.8 (main, Dec 10 2021, 06:31:09) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)]!"
実行出来ています。
ECR にイメージをプッシュ
このイメージをECRにプッシュします。
$ aws ecr get-login-password | docker login --username AWS --password-stdin アカウントID.dkr.ecr.リージョン.amazonaws.com $ docker tag test:latest アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest $ docker push アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest
コンテナ Lambda のデプロイ
CloudFormationテンプレートを使い、コンテナ Lambda をデプロイします。
$ aws cloudformation deploy \ --stack-name lambda-container-test \ --template-file ./cfn.yml \ --parameter-overrides EcrImageUri=アカウントID.dkr.ecr.リージョン.amazonaws.com/test:latest \ --capabilities CAPABILITY_IAM
--template-body
引数で CloudFormation テンプレートを指定し、--parameters
で ECR イメージの URI を指定します。
AWSコンソールからCloudFormationスタックを作成することも出来ます。
コンテナLambdaの動作確認
最後に、Lambda関数を動作確認します。
$ aws lambda invoke \ --function-name lambda-container-test-LambdaFunc-xxx \ --invocation-type RequestResponse \ --payload '{}' response.json && cat response.json { "StatusCode": 200, "ExecutedVersion": "$LATEST" } "Hello from AWS Lambda using Python3.9.8 (main, Dec 10 2021, 06:31:09) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)]!"
無事実行できました。
AWS SAMでもデプロイ可能
コンテナ Lambdaをデプロイしたい場合、AWS サーバーレスアプリケーションモデル(AWS SAM)を使うアプローチも有力です。
AWSのAPIを逐一呼び出さずに済み、ディベロッパーの開発フローに寄り添ったコマンド体系が提供されています。
詳細は次のドキュメントを参照ください。
それでは。